package com.fessc.develop.service.impl;

import com.fessc.develop.entity.dbvo.SettleTrade;
import com.fessc.develop.entity.dbvo.TCheckDetail;
import com.fessc.develop.entity.dbvo.TCheckResultList;
import com.fessc.develop.entity.dbvo.TPayment;
import com.fessc.develop.model.enums.EnumCheckType;
import com.fessc.develop.model.enums.EnumPaymentStatus;
import com.fessc.develop.model.enums.EnumResultType;
import com.fessc.develop.service.interfaces.*;
import com.fessc.develop.utils.BusiUtil;
import com.fessc.develop.utils.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

@Slf4j
@Service
public class BankCheckResultServiceImpl implements BankCheckResultService {

    @Resource
    private ITPaymentService paymentService;

    @Resource
    private ITCheckResultListService checkResultListService;

    @Resource
    private ISettleTradeService settleTradeService;

    @Resource
    private ISettleTradeListService settleTradeListService;

    @Override
    public void checkPayment(List<TCheckDetail> checkDetailList, String bankId, String batchNo) {
        log.info("删除预付款对账结果：" + batchNo);
        checkResultListService.deleteCheckResultListByBatchNo(bankId, batchNo, EnumCheckType.PRE_PAYMENT_CHECK.toString());
        //循环解析预扣款对账不符明细
        for (TCheckDetail detail : checkDetailList) {
            String errorMsg = "";
            // 错误类型0：状态不一致，1：互联互通有记录，银行未返回该记录，2：互联互通无记录，银行返回该记录
            if (BusiUtil.isEquals(detail.getErrorType(), "0")) {
                errorMsg = "预付款-互联互通与银行对账结果不一致，订单编号：" + detail.getSuborderno() + "，互联互通状态：" + detail.getStatus() + "，银行返回状态：" + detail.getBankStatus();
                if (BusiUtil.isEquals(detail.getBankStatus(), EnumResultType.CHECK_BANK_SUCCESS.getStatusCode())) {
                    // 预扣款对账返回状态为交易成功，以对账结果为准，重新更新交易状态
                    log.info("预付款对账返回状态为交易成功，以对账结果为准，更新交易状态为成功：" + detail.getSuborderno());
                    TPayment tPayment = new TPayment();
                    tPayment.setSuborderno(detail.getSuborderno());
                    tPayment.setPaymentStatus(EnumPaymentStatus.PAYMENT_SUCCESS.toString());
                    tPayment.setPaymentLog(BusiUtil.nvl(detail.getBankLog(),""));
                    tPayment.setBankRefids(detail.getBankRefids());
                    paymentService.updatePrePaymentStatusRefidsLog(tPayment, EnumPaymentStatus.PAYMENT_SUCCESS.toString());
                } else if (BusiUtil.isEquals(detail.getBankStatus(), EnumResultType.CHECK_BANK_FAIL.getStatusCode())) {
                    // 预扣款对账返回状态为交易失败，以对账结果为准，重新更新交易状态
                    log.info("预付款对账返回状态为交易失败，以对账结果为准，更新交易状态为失败：" + detail.getSuborderno());
                    TPayment tPayment = new TPayment();
                    tPayment.setSuborderno(detail.getSuborderno());
                    tPayment.setPaymentStatus(EnumResultType.CHECK_BANK_FAIL.getStatusCode());
                    tPayment.setPaymentLog(BusiUtil.nvl(detail.getBankLog(), EnumPaymentStatus.PAYMENT_FAIL_LOG.toString()));
                    paymentService.updatePrePaymentStatusRefidsLog(tPayment, EnumPaymentStatus.PAYMENT_FAIL.toString());
                }
            } else if (BusiUtil.isEquals(detail.getErrorType(), "1")) {
                errorMsg = "预付款-互联互通有记录，银行未返回对账结果，订单编号：" + detail.getSuborderno();
            } else if (BusiUtil.isEquals(detail.getErrorType(), "2")) {
                errorMsg = "预付款-互联互通无记录，银行有返回对账结果，订单编号：" + detail.getSuborderno();
            }
            TCheckResultList checkResultList = getTCheckResultList(detail, errorMsg, batchNo, EnumCheckType.PRE_PAYMENT_CHECK.toString());
            log.info("预付款对账结果信息：" + errorMsg);
            log.info("保存预付款对账结果：日期" + DateUtil.dateToString(detail.getCheckDate(),DateUtil.DATE_FORMAT) + "，批次号" + batchNo);
            checkResultListService.save(checkResultList);
        }
    }

    @Override
    public void checkRefund(List<TCheckDetail> checkDetailList, String bankId, String batchNo) {
        log.info("删除预付款退款对账结果：" + batchNo);
        checkResultListService.deleteCheckResultListByBatchNo(bankId, batchNo, EnumCheckType.REFUND_CHECK.toString());
        //循环解析预扣款退款对账不符明细
        for (TCheckDetail detail : checkDetailList) {
            String errorMsg = "";
            if (BusiUtil.isEquals(detail.getErrorType(), "0")) {
                errorMsg = "预付款退款-互联互通与银行对账结果不一致，订单编号：" + detail.getSuborderno() + "，互联互通状态：" + detail.getStatus() + "，银行返回状态：" + detail.getBankStatus();
                if (BusiUtil.isEquals(detail.getBankStatus(), EnumResultType.CHECK_BANK_SUCCESS.getStatusCode())) {
                    // 对账返回状态为交易成功，以对账结果为准，重新更新交易状态
                    log.info("预付款退款对账返回状态为交易成功，以对账结果为准，更新交易状态为成功：" + detail.getSuborderno());
                    TPayment tPayment = new TPayment();
                    tPayment.setSuborderno(detail.getSuborderno());
                    tPayment.setRefundStatus(EnumPaymentStatus.PAYMENT_SUCCESS.toString());
                    tPayment.setRefundLog(BusiUtil.nvl(detail.getBankLog(), ""));
                    tPayment.setRefundRefids(detail.getBankRefids());
                    tPayment.setSend2("N");
                    paymentService.updateRefundStatusRefidsLog(tPayment, EnumPaymentStatus.PAYMENT_SUCCESS.toString());
                } else if (BusiUtil.isEquals(detail.getBankStatus(), EnumResultType.CHECK_BANK_FAIL.getStatusCode())) {
                    // 对账返回状态为交易失败，以对账结果为准，重新更新交易状态
                    log.info("预付款退款对账返回状态为交易失败，以对账结果为准，更新交易状态为失败：" + detail.getSuborderno());
                    TPayment tPayment = new TPayment();
                    tPayment.setSuborderno(detail.getSuborderno());
                    tPayment.setRefundStatus(EnumResultType.CHECK_BANK_FAIL.getStatusCode());
                    tPayment.setRefundLog(BusiUtil.nvl(detail.getBankLog(), EnumPaymentStatus.PAYMENT_FAIL_LOG.toString()));
                    paymentService.updateRefundStatusRefidsLog(tPayment, EnumPaymentStatus.PAYMENT_FAIL.toString());
                }
            } else if (BusiUtil.isEquals(detail.getErrorType(), "1")) {
                errorMsg = "预付款退款-互联互通有记录，银行未返回对账结果，订单编号：" + detail.getSuborderno();
            } else if (BusiUtil.isEquals(detail.getErrorType(), "2")) {
                errorMsg = "预付款退款-互联互通无记录，银行有返回对账结果，订单编号：" + detail.getSuborderno();
            }
            TCheckResultList checkResultList = getTCheckResultList(detail, errorMsg, batchNo, EnumCheckType.REFUND_CHECK.toString());
            log.info("预付款退款对账结果信息：" + errorMsg);
            log.info("保存预付款退款对账结果：日期" + DateUtil.dateToString(detail.getCheckDate(),DateUtil.DATE_FORMAT) + "，批次号" + batchNo);
            checkResultListService.save(checkResultList);
        }
    }

    @Override
    public void checkSettle(List<TCheckDetail> checkDetailList, String bankId, String batchNo) {
        log.info("删除跨境付汇对账结果：" + batchNo);
        checkResultListService.deleteCheckResultListByBatchNo(bankId, batchNo, EnumCheckType.SETTLE_TRADE_CHECK.toString());
        //循环解析跨境付汇对账不符明细
        for (TCheckDetail detail : checkDetailList) {
            String errorMsg = "";
            if (BusiUtil.isEquals(detail.getErrorType(), "0")) {
                errorMsg = "跨境付汇-互联互通与银行对账结果不一致，订单编号：" + detail.getSuborderno() + "，互联互通状态：" + detail.getStatus() + "，银行返回状态：" + detail.getBankStatus();
                if (BusiUtil.isEquals(detail.getBankStatus(), EnumResultType.CHECK_BANK_SUCCESS.getStatusCode())) {
                    // 对账返回状态为交易成功，以对账结果为准，重新更新交易状态
                    log.info("跨境付汇对账返回状态为交易成功，以对账结果为准，重新更新交易状态为成功：" + detail.getSuborderno());
                    SettleTrade settleTrade = new SettleTrade();
                    settleTrade.setOrderno(detail.getSuborderno());
                    settleTrade.setReviewStatus(EnumPaymentStatus.SETTLE_REVIEW_SUCCESS.toString()); //银行审核付款成功
                    settleTrade.setDealDate(DateUtil.getCurrentLocalDateTime());  //当前时间
                    settleTrade.setDealPerformer(settleTrade.getOrgCode()); //银行直连机构号
                    settleTrade.setReviewDate(DateUtil.getCurrentLocalDateTime());  //当前时间
                    settleTrade.setReviewPerformer(settleTrade.getOrgCode());  //银行直连机构号
                    settleTrade.setSerialnumber(settleTrade.getSettleId());  //没有汇总订单的付款流水号，用settle_id代替
                    settleTrade.setSend2(EnumPaymentStatus.SETTLE_CANCEL_SEND.toString());
                    // 更新跨境订单交易表
                    log.info("更新跨境付汇订单状态为成功：" + settleTrade.getOrderno());
                    settleTradeService.updateSettleTradeStatusRefidsLog(settleTrade, EnumPaymentStatus.PAYMENT_SUCCESS.toString()); //更新交易成功状态
                    // 更新跨境订单明细表
                    log.info("更新跨境付订单汇明细状态为已跨境付汇：" + settleTrade.getOrderno());
                    settleTradeListService.updateSettleTradeListStatus(settleTrade.getSettleId(), "Y");
                } else if (BusiUtil.isEquals(detail.getBankStatus(), EnumResultType.CHECK_BANK_FAIL.getStatusCode())) {
                    // 对账返回状态为交易失败，以对账结果为准，重新更新交易状态
                    log.info("跨境付汇对账返回状态为交易失败，以对账结果为准，更新交易状态为失败：" + detail.getSuborderno());
                    SettleTrade settleTrade = new SettleTrade();
                    settleTrade.setOrderno(detail.getSuborderno());
                    settleTrade.setReviewStatus(EnumPaymentStatus.SETTLE_REVIEW_FAIL.toString()); //银行审核付款失败
                    settleTrade.setRejectDate(DateUtil.getCurrentLocalDateTime());  //当前时间
                    settleTrade.setRejectPerformer(settleTrade.getOrgCode()); //银行直连机构号
                    settleTrade.setRemark("银行驳回交易失败原因：" + BusiUtil.nvl(detail.getBankLog(), EnumPaymentStatus.PAYMENT_FAIL_LOG.toString()));  //失败原因
                    settleTrade.setCancelSend(EnumPaymentStatus.SETTLE_CANCEL_SEND.toString());
                    // 更新跨境订单交易表
                    log.info("更新跨境付汇订单状态为失败：" + settleTrade.getOrderno());
                    settleTradeService.updateSettleTradeStatusRefidsLog(settleTrade, EnumPaymentStatus.PAYMENT_FAIL.toString()); //更新交易失败状态
                    // 更新跨境订单明细表
                    log.info("更新跨境付订单汇明细状态为未跨境付汇：" + settleTrade.getOrderno());
                    settleTradeListService.updateSettleTradeListStatus(settleTrade.getSettleId(), "N");
                }
            } else if (BusiUtil.isEquals(detail.getErrorType(), "1")) {
                errorMsg = "跨境付汇-互联互通有记录，银行未返回对账结果，订单编号：" + detail.getSuborderno();
            } else if (BusiUtil.isEquals(detail.getErrorType(), "2")) {
                errorMsg = "跨境付汇-互联互通无记录，银行有返回对账结果，订单编号：" + detail.getSuborderno();
            }
            TCheckResultList checkResultList = getTCheckResultList(detail, errorMsg, batchNo, EnumCheckType.SETTLE_TRADE_CHECK.toString());
            log.info("跨境付汇对账结果信息：" + errorMsg);
            log.info("保存跨境付汇对账结果：日期" + DateUtil.dateToString(detail.getCheckDate(),DateUtil.DATE_FORMAT) + "，批次号" + batchNo);
            checkResultListService.save(checkResultList);
        }
    }

    private static TCheckResultList getTCheckResultList(TCheckDetail detail, String errorMsg, String batchNo, String checkType) {
        TCheckResultList checkResultList = new TCheckResultList();
        checkResultList.setCheckDate(detail.getCheckDate());
        checkResultList.setCheckType(checkType);
        checkResultList.setBatchNo(batchNo);
        checkResultList.setBankId(detail.getBankId());
        checkResultList.setSuborderno(detail.getSuborderno());
        checkResultList.setCheckLog(errorMsg);
        checkResultList.setCheckTime(DateUtil.getCurrentLocalDateTime());
        return checkResultList;
    }

}
